package com.tankgame;

import javafx.scene.layout.Pane;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;

//坦克大战的绘图区域
//为了监听键盘事件，实现KeyListener
//为了让Panel不停重绘子弹，需要将MyPanel实现一个Runnabl,当作一个线程使用
public class MyPanel extends JPanel implements KeyListener,Runnable {
    //定义我的坦克
    Hero hero=null;
    //定义敌人坦克
    Vector<EnemyTank> enTanks=new Vector<>();
    //定义一个存放Node对象的vector，用于回复敌人坦克的坐标和方向
    Vector<Node> nodes=new Vector<>();
    //定义一个Vector,用于存放炸弹
    //说明，当子弹击中坦克时，加入一个Bomb对象到bombs
    Vector<Bomb> bombs = new Vector<>();
    int enTankSize=3;

    //定义三张炸弹图片，用于显示爆炸效果
    Image image1=null;
    Image image2=null;
    Image image3=null;
    public MyPanel(String key){
        Recorder.getNodesAndEnemyTankRec();
        //将MyPanel对象的enemyTankes设置给Recorder的enemyTanks
        Recorder.setEnemyTanks( enTanks);
        hero=new Hero(500,100);//初始化自己的坦克
        hero.setSpeed(3);//定义坦克移动速度

        switch (key){
            case "1":
                //初始化敌人坦克
                for(int i=0;i<enTankSize;i++){
                    //创建一个敌人的坦克
                    EnemyTank enemyTank=new EnemyTank((100*(i+1)),0);
                    //将enemyTanks设置给enemyTank
                    enemyTank.setEnemyTanks(enemyTank.enemyTanks);
                    //设置方向
                    enemyTank.setDirect(2);
                    //启动敌人坦克线程，让他动起来
                    new Thread(enemyTank).start();
                    //给该enemyTank加入一颗子弹
                    Shot shot=new Shot(enemyTank.getX()+20,enemyTank.getY()+60,enemyTank.getDirect());
                    //加入enemyTank的Vector成员
                    enemyTank.shots.add(shot);
                    //启动shot对象
                    new Thread(shot).start();
                    //加入
                    enTanks.add(enemyTank);
                }
                //初始化图片对象
                image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));
                image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));
                image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));
                break;
            case "2"://继续上局游戏
                //初始化敌人坦克
                for(int i=0;i<nodes.size();i++){
                    Node node=nodes.get(i);
                    //创建一个敌人的坦克
                    EnemyTank enemyTank=new EnemyTank(node.getX(), node.getY());
                    //将enemyTanks设置给enemyTank
                    enemyTank.setEnemyTanks(enemyTank.enemyTanks);
                    //设置方向
                    enemyTank.setDirect(node.getDirect());
                    //启动敌人坦克线程，让他动起来
                    new Thread(enemyTank).start();
                    //给该enemyTank加入一颗子弹
                    Shot shot=new Shot(enemyTank.getX()+20,enemyTank.getY()+60,enemyTank.getDirect());
                    //加入enemyTank的Vector成员
                    enemyTank.shots.add(shot);
                    //启动shot对象
                    new Thread(shot).start();
                    //加入
                    enTanks.add(enemyTank);
                }
                //初始化图片对象
                image1=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_1.gif"));
                image2=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_2.gif"));
                image3=Toolkit.getDefaultToolkit().getImage(Panel.class.getResource("/bomb_3.gif"));
                break;
            default:
                System.out.println("输入有误");
        }



    }

    //编写方法，显示我方击毁敌方坦克的信息
    public void showInfo(Graphics g){
        //画出玩家的总成绩
        g.setColor(Color.BLACK);
        Font font = new Font("宋体",Font.BOLD,25);
        g.setFont(font);
        g.drawString("您累计击毁敌方坦克",1020,30);
        drawTank(1020,60,g,0, 1);//画出一个覅放坦克
        g.setColor(Color.black);//这里需要重新设置成黑色
        g.drawString(Recorder.getAllEnemyTankNum()+"",1080,100);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        g.fillRect(0,0,1000,750);//填充矩形，默认黑色
        showInfo(g);
        if (hero!=null&&hero.isLive){
            //画出自己坦克-封装方法
            drawTank(hero.getX(), hero.getY(), g,hero.getDirect(),0);
        }

        //画出hero射击的子弹
        //hero的子弹集合shots，遍历取出绘制
        for (int i=0;i<hero.shots.size();i++){
            Shot shot = hero.shots.get(i);
            if(shot!=null&&shot.isLive!=false){
                System.out.println("子弹被绘制");
    //            g.fill3DRect(hero.shot.x,hero.shot.y,1,1,false);
                g.draw3DRect(shot.x,shot.y,2,2,false);
            }else {//如果该shot对象已经无效了，就从shots集合中拿掉
                hero.shots.remove(shot);
            }
        }

        //如果bombs集合中有对象，就画出
        for(int i=0;i<bombs.size();i++){
            //取出炸弹
            Bomb bomb = bombs.get(i);
            //根据当前这个bomb对象的life值去画出对应的图片
            if(bomb.life>6){
                g.drawImage(image1, bomb.x, bomb.y, 60,60,this);
            }else if(bomb.life>3){
                g.drawImage(image2, bomb.x, bomb.y, 60,60,this);
            }else{
                g.drawImage(image3, bomb.x, bomb.y, 60,60,this);
            }
            //让这个炸弹的生命值减少
            bomb.lifeDown();
            //如果bomb life为0，就从bombs的集合中删除
            if(bomb.life==0){
                bombs.remove(bomb);
            }
        }

        //画出敌人的坦克,遍历Vector
        for(int i=0;i< enTanks.size();i++){
            //从Vector取出坦克
            EnemyTank enemyTank=enTanks.get(i);
            //判断当前坦克是否存活
            if(enemyTank.isLive){
                drawTank(enemyTank.getX(), enemyTank.getY(), g,enemyTank.getDirect(),1);
                //画出enemyTank所有子弹
                for (int j=0;j<enemyTank.shots.size();j++){
                    //取出子弹
                    Shot shot=enemyTank.shots.get(j);
                    //绘制
                    if(shot.isLive){
                        g.draw3DRect(shot.x, shot.y,1,1,false);
                    }else {
                        //从Vector移除
                        enemyTank.shots.remove(shot);
                    }
                }
            }

        }

    }

    //编写方法，画出坦克
    /*
    * x 坦克的左上角x坐标
    * y 坦克的左上角y坐标
    * g 画笔
    * direct 坦克方向（上下左右）
    * type 坦克类型
    * */
    public void drawTank(int x,int y,Graphics g,int direct,int type){
        switch(type){
            case 0://自己的坦克
                g.setColor(Color.cyan);
                break;
            case 1://敌人的坦克
                g.setColor(Color.yellow);
                break;
        }

        //根据坦克的方向来绘制对应形状的坦克
        //direct表示方向(0:向上 1:向右 2:向下 3:向左)
        switch (direct){
            case 0:
                //画出坦克左边的轮子
                g.fill3DRect(x, y, 10,60,false);
                //画出坦克右边的轮子
                g.fill3DRect(x+30, y, 10,60,false);
                //画出坦克的盖子
                g.fill3DRect(x+10, y+10, 20,40,false);
                //画出圆行的盖子
                g.fillOval(x+10,y+20,20,20);
                //画出炮筒
                g.drawLine(x+20,y+30,x+20,y);
                break;
            case 1://表示向右
                //画出坦克左边的轮子
                g.fill3DRect(x-10, y+10, 60,10,false);
                //画出坦克右边的轮子
                g.fill3DRect(x-10, y+40, 60,10,false);
                //画出坦克的盖子
                g.fill3DRect(x, y+20, 40,20,false);
                //画出圆行的盖子
                g.fillOval(x+10,y+20,20,20);
                //画出炮筒
                g.drawLine(x+30,y+30,x+50,y+30);
                break;
            case 2://表示向下
                //画出坦克左边的轮子
                g.fill3DRect(x, y, 10,60,false);
                //画出坦克右边的轮子
                g.fill3DRect(x+30, y, 10,60,false);
                //画出坦克的盖子
                g.fill3DRect(x+10, y+10, 20,40,false);
                //画出圆行的盖子
                g.fillOval(x+10,y+20,20,20);
                //画出炮筒
                g.drawLine(x+20,y+30,x+20,y+60);
                break;
            case 3://表示向左
                //画出坦克左边的轮子
                g.fill3DRect(x-10, y+10, 60,10,false);
                //画出坦克右边的轮子
                g.fill3DRect(x-10, y+40, 60,10,false);
                //画出坦克的盖子
                g.fill3DRect(x, y+20, 40,20,false);
                //画出圆行的盖子
                g.fillOval(x+10,y+20,20,20);
                //画出炮筒
                g.drawLine(x+30,y+30,x-10,y+30);
                break;
            default:
                System.out.println("暂时无处理");
        }
    }

    //如果我们的坦克可以发射多颗子弹
    //在判断我方子弹是否击中敌人坦克，就需要把我们的子弹集合中
    //所有的子弹，都取出和敌人的所有坦克，进行判断
    public void hitEnemyTank(){
        //遍历我方的子弹
        for (int j=0;j<hero.shots.size();j++){
            Shot shot = hero.shots.get(j);
            //判断是否击中敌人坦克
            if(shot!=null&&shot.isLive){//当我的子弹还存活
                //遍历敌人所有的坦克
                for(int i=0;i<enTanks.size();i++){
                    EnemyTank enemyTank = enTanks.get(i);
                    hitTank(shot, enemyTank);
                }
            }
        }
    }

    //编写方法，判断敌人坦克是否击中我的坦克
    public void hirHero(){
        //遍历所有敌人坦克
        for(int i=0 ;i<enTanks.size();i++){
            //取出敌人坦克
            EnemyTank enemyTank = enTanks.get(i);
            //遍历enemyTank对象的所有子弹
            for (int j=0;j<enemyTank.shots.size();j++){
                //取出子弹
                Shot shot = enemyTank.shots.get(j);
                //判断shot是否击中
                if (hero.isLive&&shot.isLive){
                    hitTank(shot,hero);
                }
            }
        }
    }

    //编写方法，判断我方的子弹是否击中敌人坦克
    //什么时候判断我方子弹是否击中敌人坦克？run方法
    //后面将enemyTank改成tank名称
    public void hitTank(Shot s,Tank enemyTank){
        //判断s击中坦克
        switch (enemyTank.getDirect()){
            case 0://坦克向上
            case 2://坦克向下
                if(s.x>enemyTank.getX() &&s.x<enemyTank.getX()+40 && s.y>enemyTank.getY()&&s.y<enemyTank.getY()+60 ){
                    s.isLive=false;
                    enemyTank.isLive=false;
                    //当我的子弹击中敌人坦克后，将enemyTank从Vector拿掉
                    enTanks.remove(enemyTank);
                    //当我方击毁一个敌人坦克时，就对enemyTankNum++
                    //因为enemyTank可以是Hero也可以是EnemyTank
                    if(enemyTank instanceof EnemyTank){
                        Recorder.addAllEnemyTankNum();
                    }
                    //创建Bomb对象，加入到bombs集合
                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombs.add(bomb);
                }
                break;
            case 1://坦克向右
            case 3://坦克向左
                if(s.x>enemyTank.getX()&&s.x<enemyTank.getX()+60 && s.y>enemyTank.getY()&&s.y<enemyTank.getY()+40){
                    s.isLive=false;
                    enemyTank.isLive=false;
                    //当我的子弹击中敌人坦克后，将enemyTank从Vector拿掉
                    enTanks.remove(enemyTank);
                    //当我方击毁一个敌人坦克时，就对enemyTankNum++
                    //因为enemyTank可以是Hero也可以是EnemyTank
                    if(enemyTank instanceof EnemyTank){
                        Recorder.addAllEnemyTankNum();
                    }
                    //创建Bomb对象，加入到bombs集合
                    Bomb bomb = new Bomb(enemyTank.getX(), enemyTank.getY());
                    bombs.add(bomb);
                }
                break;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        //根据用户按下的不同键，来处理小球的移动（上下左右的键）
        if(e.getKeyCode()== KeyEvent.VK_W){//KeyEvent.VK_DOWN就是向下的箭头对应的code
            //改变坦克方向
            hero.setDirect(0);
            //修改坦克的坐标y -= 1
            if(hero.getY()>0){
                hero.moveUp();
            }
        }else if(e.getKeyCode()== KeyEvent.VK_D){
            hero.setDirect(1);
            if (hero.getX()+60<1000){
                hero.moveRight();
            }
        }else if(e.getKeyCode()== KeyEvent.VK_S){
            hero.setDirect(2);
            if (hero.getY()+100<750){
                hero.moveDown();
            }
        }else if(e.getKeyCode()== KeyEvent.VK_A){
            hero.setDirect(3);
            if (hero.getX()>5){
                hero.moveLeft();
            }
        }

        //如果用户安县的是J，就发射
        if(e.getKeyCode()==KeyEvent.VK_J){
            //判断hero的子弹是否销毁
//            if(hero.shot == null || !hero.shot.isLive){
                hero.shotEnemyTank();
//            }
        }
        //让面板重绘
        this.repaint();
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void run() {//每个100毫秒重绘区域,刷新绘图区域
        while (true) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //判断所有子弹是否击中敌人
            this.hitEnemyTank();
            //判断敌人是否击中自己
            hirHero();
            this.repaint();
        }
    }
}
